package com.batunite.livedatabinding.views

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import com.batunite.livedatabinding.R
import com.batunite.livedatabinding.model.Map90Data
import java.util.LinkedList
import kotlin.math.ceil
import kotlin.math.max


/**
 * author : r
 * time   : 2023/8/25 10:21 AM
 * desc   : 主界面
 */
class GameView : View {
    private var playerStartRow: Int = 0
    private var playerStartCol: Int = 0
    private var playerEndRow: Int = 0
    private var playerEndCol: Int = 0
    private val useAnim: Boolean = false
    private var isAnimRunning: Boolean = false
    private var gameStateListener: GameStateListener? = null
    private var count = 99
    var sum = 0

    // 当前朝向
    private var CURRENT_ORIENTATION: Int = MOVE_TO_DOWN
    var MAP_H: Int = 16  // 地图的行数
    var MAP_L: Int = 16  // 地图的列数

    var mWidth: Int = 0 // view的宽
    var mHeight: Int = 0 // view的高

    var drawBitmapWidth = 0
    var drawBitmapHeight = 0

    companion object {
        //     当前坐标的属性值
        val WALL: Int = 1 //墙
        val EMPTY: Int = 0 // 空
        val GAME_MAN: Int = 4 // 玩家
        val BOX_NOT: Int = 3 // 空箱子（待移动）
        val BOX_FILL: Int = 5 // 满箱子
        val FLOWER: Int = 2 // 花（目的地/目标点）
        val FLOWER_MAN: Int = 6 // 花和人重叠在一起

        // 移动方向
        val MOVE_TO_UP: Int = 0
        val MOVE_TO_LEFT: Int = 1
        val MOVE_TO_RIGHT: Int = 2
        val MOVE_TO_DOWN: Int = 3
        private const val animationDuration = 15L
    }

    /*
    * 图片资源赋值
    * */
    val bitmap_wall: Bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.c_wall)
    val bitmap_empty: Bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.c_road)
    val bitmap_boxNot: Bitmap =
        BitmapFactory.decodeResource(getResources(), R.drawable.c_box)
    val bitmap_boxFill: Bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.c_box_fill)
    val bitmap_flower: Bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.c_flower)
    val bitmap_flowerAndMan: Bitmap =
        BitmapFactory.decodeResource(getResources(), R.drawable.c_man_down)

    private fun getBitmap_gameMan(type: Int = MOVE_TO_DOWN): Bitmap {
        when (type) {
            MOVE_TO_UP ->
                return BitmapFactory.decodeResource(getResources(), R.drawable.c_man_up)

            MOVE_TO_LEFT ->
                return BitmapFactory.decodeResource(getResources(), R.drawable.c_man_left)

            MOVE_TO_RIGHT ->
                return BitmapFactory.decodeResource(getResources(), R.drawable.c_man_right)

            else ->
                return BitmapFactory.decodeResource(getResources(), R.drawable.c_man_down)
        }
    }

    var paint: Paint = Paint()

    // 关数
    var level: Int = 0
    var mapArray = Array(MAP_H) {
        IntArray(MAP_L)
    }

    private val squares = Array(MAP_H) { Array(MAP_L) { Square() } }

    // 网格中方格边缘
    private val gridBounds: Array<Array<Rect>> = Array(MAP_H) { row ->
        Array(MAP_L) { col ->
            Rect()
        }
    }

    // 是否需要重绘制
    var canInvalidate = false

    // 保存每一步地图状态
    private val mapTempList = LinkedList<Array<IntArray>>()

    //二维地图数据
    //我们在自定义 View 继承 View 的时候，1 和 2 是必须重写的。
    //第 1 个构造函数是在 java 代码中声明一个 View 时所用。
    constructor(context: Context) : this(context, null)

    //第 2 个构造函数是在布局文件中声明一个 View 时所用。参数 attrs 可以获取在布局文件中定义的 View 的属性值。
    //<?xml version="1.0" encoding="utf-8"?>
    //<resources>
    //    <attr name="textViewColorStyle" format="reference" />
    //</resources>
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)

    //构造函数 3 和 4 是可选的，defStyleAttr 是在主题中定义的，是一个指向 style 的 reference。
    //  <item name="android:textViewStyle">@style/MyTextViewStyle</item>
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
    }

    fun setGameStateListener(gameStateListener: GameStateListener) {
        this.gameStateListener = gameStateListener
    }

    //defStyleRes 和 2 类似，使用 style。只不过 2 是 xml 布局文件中使用，这里是 Java 代码中使用。
    //defStyleAttr 的优先级要高于 defStyleRes，只有当 defStyleAttr 为 0 的时候，
    // 才有可能（有可能是因为 1 2 3 的方式优先级更高）使用 defStyleRes。
    constructor(
        context: Context,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int
    ) : super(
        context,
        attrs,
        defStyleAttr,
        defStyleRes
    )

    // 确定view的宽高
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        mWidth = MeasureSpec.getSize(widthMeasureSpec)
        mHeight = MeasureSpec.getSize(heightMeasureSpec)
        drawBitmapWidth = ceil(mWidth.toDouble() / MAP_L).toInt()
        drawBitmapHeight = ceil(mHeight.toDouble() / MAP_H).toInt()

        for (h in 0 until MAP_H) {
            for (l in 0 until MAP_L) {
                squares[h][l].startX = drawBitmapWidth * l
                squares[h][l].targetX = drawBitmapWidth * l
                squares[h][l].startY = drawBitmapHeight * h
                squares[h][l].targetY = drawBitmapHeight * h
            }
        }

        Log.d(">>>>", "measured: ");
//        MAP_L = mWidth / bitmap_flower.width
//        MAP_H = mWidth / bitmap_flower.height
//        Log.d(">>>>", "onMeasure: $mWidth $mHeight $MAP_L $MAP_H")
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {

        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {

            }

            MotionEvent.ACTION_MOVE -> {

            }

            MotionEvent.ACTION_UP -> {
                //检查手指触摸的位置
                for (row in 0 until MAP_H) {
                    for (col in 0 until MAP_L) {
                        if (gridBounds[row][col].contains(event.x.toInt(), event.y.toInt())) {
                            // 触摸点在第 row 行、第 col 列的网格中 查找是否可到达
                            searchPathAlgorithm(row, col)
                            return true // 已处理该事件，返回 true 表示消耗该事件
                        }
                    }
                }
            }
        }
        return true
    }

    /**
     * 目标点寻路
     */
    private fun searchPathAlgorithm(row: Int, col: Int) {
        // 查找人物 判断人物是否可到达触摸点
        val pair = findGameManPosition()
        if (pair.first == row && pair.second == col) {
            return
        }

        val start = intArrayOf(pair.first, pair.second) // 人物起始位置
        val target = intArrayOf(row, col) // 目标位置
        val path = SearchPathHelper.findPath(mapArray, start, target)
        if (path != null) {
            val convertToDirections = SearchPathHelper.convertToDirections(path)
            convertToDirections?.forEach {
                when (it) {
                    MOVE_TO_UP -> {
                        moveUp()
                    }

                    MOVE_TO_LEFT -> {
                        moveLeft()
                    }

                    MOVE_TO_RIGHT -> {
                        moveRight()
                    }

                    MOVE_TO_DOWN -> {
                        moveDown()
                    }
                }
            }
            for (point in path) {
                Log.d(">>>>", "(" + point!![0] + ", " + point!![1] + ")")
            }
        } else {
            Log.d(">>>>", "searchPathAlgorithm: 无法找到路径！")
        }
    }


    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        drawCount++
        Log.d(">>>>", "onDraw: --> $drawCount")
        for (h in 0 until MAP_H) {
            for (l in 0 until MAP_L) {
//                二维数组的下标 --> 相当于地图上的一个点
                val bitmap_point: Int = mapArray.get(h).get(l)

                /*等分网格
                 * Left相当于X，(mWidth / MAP_L) * l 按宽度等分 取l列
                 * Top相当于Y (mHeight / MAP_H) * h, 按高度等分 取h行
                 *Right - X ：长方形的长
                 *Bottom - Y：长方形的宽
                 * */
                var left = drawBitmapWidth * l
                var top = drawBitmapHeight * h
                var right = drawBitmapWidth * (l + 1)
                var bottom = drawBitmapHeight * (h + 1)
                val rect = Rect(
                    left,
                    top,
                    right,
                    bottom
                )
                gridBounds[h][l] = rect
                //  根据二维数组中的值绘制相应的图
                canvas?.drawBitmap(bitmap_empty, null, rect, paint)
                when (bitmap_point) {
                    WALL ->
                        canvas?.drawBitmap(bitmap_wall, null, rect, paint)

//                    EMPTY ->

                    GAME_MAN -> {
                        /*canvas?.drawBitmap(
                            getBitmap_gameMan(CURRENT_ORIENTATION),
                            null,
                            rect,
                            paint
                        )*/
                    }

                    BOX_NOT ->
                        canvas?.drawBitmap(bitmap_boxNot, null, rect, paint)

                    BOX_FILL ->
                        canvas?.drawBitmap(bitmap_boxFill, null, rect, paint)

                    FLOWER ->
                        canvas?.drawBitmap(bitmap_flower, null, rect, paint)

                    FLOWER_MAN -> {
                        canvas?.drawBitmap(bitmap_flower, null, rect, paint)
                    }

                    else -> Log.d("++++", "onDraw: ")
                }
            }
        }
        canvas?.drawBitmap(
            getBitmap_gameMan(CURRENT_ORIENTATION),
            null,
            Rect(
                squares[playerStartRow][playerStartCol].startX,
                squares[playerStartRow][playerStartCol].startY,
                squares[playerStartRow][playerStartCol].startX + drawBitmapWidth,
                squares[playerStartRow][playerStartCol].startY + drawBitmapHeight
            ),
            paint
        )
        // 如果有方块正在进行动画，则更新方块位置并触发重绘
        if (useAnim && isAnimating()) {
            Log.d(">>>>", "onDraw: = -> anim invalidate")
            updateSquarePositions()
            invalidate()
        }
    }

    /*
    * 设置地图方法并计算目标点数
    * */
    fun setMap(level: Int) {
        this.level = level
        if (level >= Map90Data.mapDataList.size) {
            gameStateListener?.competeAllLevels()
            return
        }
        count = 0
        sum = 0
        val mapData = Map90Data.mapDataList[level]
        for (h in 0 until MAP_H) {
            for (l in 0 until MAP_L) {
                if (mapData[h][l] == FLOWER) {
                    // 目标点++
                    count++
                } else if (mapData[h][l] == BOX_FILL) {
                    count++
                    // 已完成
                    sum++
                } else if (mapData[h][l] == GAME_MAN || mapData[h][l] == FLOWER_MAN) {
                    updatePlayerPosition(h, l)
                }
                mapArray[h][l] = mapData[h][l]
            }
        }
        mapTempList.add(deepCopy(mapArray))
        invalidate()  // 刷新画布
    }

    /**
     * 更新人物方块位置
     */
    private fun updatePlayerPosition(h: Int, l: Int) {
        playerStartRow = h
        playerStartCol = l
        squares[h][l].startX = drawBitmapWidth * l
        squares[h][l].targetX = drawBitmapWidth * l
        squares[h][l].startY = drawBitmapHeight * h
        squares[h][l].targetY = drawBitmapHeight * h
    }

    var nowTarget = -1 // 人物位置
    var moveTarget = -1 // 目标位置
    var nextMoveTarget = -1 // 目标位置的下一个位置

    /**
     * 找到人物在二维数组中的位置
     */
    fun findGameManPosition(): Pair<Int, Int> {
        for (h in 0 until MAP_H) {
            for (l in 0 until MAP_L) {
                // 找到人物
                if (mapArray[h][l] == GAME_MAN || mapArray[h][l] == FLOWER_MAN) {
                    return Pair(h, l)
                }
            }
        }
        return Pair(-1, -1)
    }


    /**
     * 移动到空或者花
     */
    private fun moveToEmptyOrFlower(h: Int, l: Int, nextObj: Int, type: Int = MOVE_TO_UP) {
        if (nowTarget == FLOWER_MAN) {
            nowTarget = FLOWER
        } else {
            nowTarget = EMPTY
        }
        moveTarget = nextObj
        when (type) {
            MOVE_TO_UP -> {
                mapArray[h - 1][l] = moveTarget
            }

            MOVE_TO_LEFT -> {
                mapArray[h][l - 1] = moveTarget
            }

            MOVE_TO_RIGHT -> {
                mapArray[h][l + 1] = moveTarget
            }

            MOVE_TO_DOWN -> {
                mapArray[h + 1][l] = moveTarget
            }
        }
        // 当前位置改变
        mapArray[h][l] = nowTarget
    }

    /**
     * 移动箱子
     */
    private fun boxRealMove(h: Int, l: Int, boxNow: Int, type: Int = MOVE_TO_UP) {
        // 判断人物当前是否为加花的状态 确定移动后的当前位置状态
        nowTarget = if (nowTarget == FLOWER_MAN) FLOWER else EMPTY
        var realCanMove = false
        if (nextMoveTarget == EMPTY) {
            // 箱子下一个位置是空 推过去还是空箱子
            nextMoveTarget = BOX_NOT
            if (boxNow == BOX_FILL) {
                // 满箱子移动了 需要--
                Log.d(">>>>", "EMPTY realMove--: $sum $count")
                sum = max(0, --sum)
            }
            // 人物移动到的位置需要看当前箱子的状态
            moveTarget = if (boxNow == BOX_NOT) GAME_MAN else FLOWER_MAN
            realCanMove = true
        } else if (nextMoveTarget == FLOWER) {
            // 当前箱子的下一个位置是花 变成满箱子
            realCanMove = true
            nextMoveTarget = BOX_FILL
            if (boxNow == BOX_FILL) {
                // 满箱子移动了 需要--
                Log.d(">>>>", "FLOWER BOX_FILL realMove--: $sum $count")
                sum = max(0, --sum)
            }
            sum++
            // 人物移动到的位置 根据箱子原先的状态
            moveTarget = if (boxNow == BOX_NOT) GAME_MAN else FLOWER_MAN
            Log.d(">>>>", "BOX_FILL realMove: $sum $count")
            if (sum == count) {
                showSuccess()
            }
        }
        if (realCanMove) {
            when (type) {
                MOVE_TO_UP -> {
                    mapArray[h - 2][l] = nextMoveTarget
                    mapArray[h - 1][l] = moveTarget
                }

                MOVE_TO_LEFT -> {
                    mapArray[h][l - 2] = nextMoveTarget
                    mapArray[h][l - 1] = moveTarget
                }

                MOVE_TO_RIGHT -> {
                    mapArray[h][l + 2] = nextMoveTarget
                    mapArray[h][l + 1] = moveTarget
                }

                MOVE_TO_DOWN -> {
                    mapArray[h + 2][l] = nextMoveTarget
                    mapArray[h + 1][l] = moveTarget
                }
            }
            // 当前位置改变
            mapArray[h][l] = nowTarget
        }
    }

    /**
     * 提示通关
     */
    private fun showSuccess() {
        gameStateListener?.passed(level)
        postDelayed({
            level++
            mapTempList.clear()
            setMap(level)
        }, 250)
    }


    /**
     * 只有当是空或者是目的地才可以移动
     */
    private fun canMove(obj: Int): Boolean {
        return obj == EMPTY || obj == FLOWER
    }

    //    向上移动
    fun moveUp() {
        if (!prepareMove(MOVE_TO_UP)) {
            return
        }
        nowTarget = mapArray[playerStartRow][playerStartCol]
        // 是否有移动空间 不是在边缘
        if (playerStartRow - 2 > 0) {
            moveTarget = mapArray[playerStartRow - 1][playerStartCol]
            nextMoveTarget = mapArray[playerStartRow - 2][playerStartCol]
            when (moveTarget) {
                WALL -> {
                    return
                }

                EMPTY -> {
                    canInvalidate = true
                    moveToEmptyOrFlower(playerStartRow, playerStartCol, GAME_MAN, MOVE_TO_UP)
                }
                // 上面是空箱
                BOX_NOT -> {
                    // 空箱是否可以继续移动到下一个位置
                    if (canMove(nextMoveTarget)) {
                        canInvalidate = true
                        // 当前空箱子的下一个位置是空
                        boxRealMove(playerStartRow, playerStartCol, BOX_NOT, MOVE_TO_UP)
                    }
                }
                // 上面是满箱子
                BOX_FILL -> {
                    // 满箱是否可以继续移动到下一个位置
                    if (canMove(nextMoveTarget)) {
                        canInvalidate = true
                        // 当前满箱子的下一个位置是空
                        boxRealMove(playerStartRow, playerStartCol, BOX_FILL, MOVE_TO_UP)
                    }
                }

                FLOWER -> {
                    canInvalidate = true
                    moveToEmptyOrFlower(playerStartRow, playerStartCol, FLOWER_MAN, MOVE_TO_UP)
                }
            }
        }
        if (canInvalidate) {
            Log.d("move", "moveUp: ")
            mapTempList.add(deepCopy(mapArray))
            playerMoveTo()
        } else {
            Log.d("move", "moveUp nothing")
        }
    }

    /**
     * 人物移动
     */
    private fun playerMoveTo() {
        // 得到需要移动到的坐标
        val pair = findGameManPosition()
        playerEndRow = pair.first
        playerEndCol = pair.second
        if (useAnim) {
            moveSquareTo(playerEndRow, playerEndCol)
        } else {
            updatePlayerPosition(playerEndRow, playerEndCol)
            invalidate()
        }
    }

    /**
     * 移动前的准备 查找人物位置
     */
    private fun prepareMove(moveType: Int = MOVE_TO_UP): Boolean {
        if (useAnim && isAnimating()) {
            Log.d(">>>>", "prepareMove: anim running")
            return false
        }
        CURRENT_ORIENTATION = moveType
        canInvalidate = false
        val pair = findGameManPosition()
        val h = pair.first
        val l = pair.second
        updatePlayerPosition(h, l)
        return true
    }

    fun moveDown() {
        if (!prepareMove(MOVE_TO_DOWN)) {
            return
        }
        nowTarget = mapArray[playerStartRow][playerStartCol]
        // 是否有移动空间 不是在边缘
        if (playerStartRow + 2 > 0) {
            moveTarget = mapArray[playerStartRow + 1][playerStartCol]
            nextMoveTarget = mapArray[playerStartRow + 2][playerStartCol]
            when (moveTarget) {
                WALL -> {
                    return
                }

                EMPTY -> {
                    canInvalidate = true
                    moveToEmptyOrFlower(playerStartRow, playerStartCol, GAME_MAN, MOVE_TO_DOWN)
                }
                // 上面是空箱
                BOX_NOT -> {
                    // 空箱是否可以继续移动到下一个位置
                    if (canMove(nextMoveTarget)) {
                        canInvalidate = true
                        // 当前空箱子的下一个位置是空
                        boxRealMove(playerStartRow, playerStartCol, BOX_NOT, MOVE_TO_DOWN)
                    }
                }
                // 上面是满箱子
                BOX_FILL -> {
                    // 满箱是否可以继续移动到下一个位置
                    if (canMove(nextMoveTarget)) {
                        canInvalidate = true
                        // 当前满箱子的下一个位置是空
                        boxRealMove(playerStartRow, playerStartCol, BOX_FILL, MOVE_TO_DOWN)
                    }
                }

                FLOWER -> {
                    canInvalidate = true
                    moveToEmptyOrFlower(playerStartRow, playerStartCol, FLOWER_MAN, MOVE_TO_DOWN)
                }
            }
        }
        if (canInvalidate) {
            Log.d("move", "moveDown: ")
            mapTempList.add(deepCopy(mapArray))
            playerMoveTo()
        } else {
            Log.d("move", "moveDown nothing")
        }
    }

    fun moveLeft() {
        if (!prepareMove(MOVE_TO_LEFT)) {
            return
        }
        nowTarget = mapArray[playerStartRow][playerStartCol]
        // 是否有移动空间 不是在边缘
        if (playerStartCol - 2 > 0) {
            moveTarget = mapArray[playerStartRow][playerStartCol - 1]
            nextMoveTarget = mapArray[playerStartRow][playerStartCol - 2]
            when (moveTarget) {
                WALL -> {
                    return
                }

                EMPTY -> {
                    canInvalidate = true
                    moveToEmptyOrFlower(playerStartRow, playerStartCol, GAME_MAN, MOVE_TO_LEFT)
                }
                // 上面是空箱
                BOX_NOT -> {
                    // 空箱是否可以继续移动到下一个位置
                    if (canMove(nextMoveTarget)) {
                        canInvalidate = true
                        // 当前空箱子的下一个位置是空
                        boxRealMove(playerStartRow, playerStartCol, BOX_NOT, MOVE_TO_LEFT)
                    }
                }
                // 上面是满箱子
                BOX_FILL -> {
                    // 满箱是否可以继续移动到下一个位置
                    if (canMove(nextMoveTarget)) {
                        canInvalidate = true
                        // 当前满箱子的下一个位置是空
                        boxRealMove(playerStartRow, playerStartCol, BOX_FILL, MOVE_TO_LEFT)
                    }
                }

                FLOWER -> {
                    canInvalidate = true
                    moveToEmptyOrFlower(playerStartRow, playerStartCol, FLOWER_MAN, MOVE_TO_LEFT)
                }
            }
        }
        if (canInvalidate) {
            Log.d("move", "moveLeft: ")
            mapTempList.add(deepCopy(mapArray))
            playerMoveTo()
        } else {
            Log.d("move", "moveLeft nothing")
        }
    }

    fun moveRight() {
        if (!prepareMove(MOVE_TO_RIGHT)) {
            return
        }
        nowTarget = mapArray[playerStartRow][playerStartCol]
        // 是否有移动空间 不是在边缘
        if (playerStartCol + 2 > 0) {
            moveTarget = mapArray[playerStartRow][playerStartCol + 1]
            nextMoveTarget = mapArray[playerStartRow][playerStartCol + 2]
            when (moveTarget) {
                WALL -> {
                    return
                }

                EMPTY -> {
                    canInvalidate = true
                    moveToEmptyOrFlower(playerStartRow, playerStartCol, GAME_MAN, MOVE_TO_RIGHT)
                }
                // ->面是空箱
                BOX_NOT -> {
                    // 空箱是否可以继续移动到下一个位置
                    if (canMove(nextMoveTarget)) {
                        canInvalidate = true
                        // 当前空箱子的下一个位置是空
                        boxRealMove(playerStartRow, playerStartCol, BOX_NOT, MOVE_TO_RIGHT)
                    }
                }
                // ->面是满箱子
                BOX_FILL -> {
                    // 满箱是否可以继续移动到下一个位置
                    if (canMove(nextMoveTarget)) {
                        canInvalidate = true
                        // 当前满箱子的下一个位置是空
                        boxRealMove(playerStartRow, playerStartCol, BOX_FILL, MOVE_TO_RIGHT)
                    }
                }

                FLOWER -> {
                    canInvalidate = true
                    moveToEmptyOrFlower(playerStartRow, playerStartCol, FLOWER_MAN, MOVE_TO_RIGHT)
                }
            }
        }
        if (canInvalidate) {
            Log.d("move", "moveRight: ")
            mapTempList.add(deepCopy(mapArray))
            playerMoveTo()
        } else {
            Log.d("move", "moveRight nothing")
        }
    }

    fun nextLevel() {
        showSuccess()
    }

    /**
     * 后退一步
     */
    fun onBack() {
        if (mapTempList.isNotEmpty()) {
            if (mapTempList.size > 1) {

                // 去掉刚刚走的
                val removeLast = mapTempList.removeLast()
                val removeLast2 = mapTempList.last
                mapArray = deepCopy(removeLast2)
                CURRENT_ORIENTATION = MOVE_TO_DOWN
                // 重新计算已完成步数
                sum = 0
                for (h in 0 until MAP_H) {
                    for (l in 0 until MAP_L) {
                        if (mapArray[h][l] == BOX_FILL) {
                            // 已完成
                            sum++
                        } else if (mapArray[h][l] == GAME_MAN || mapArray[h][l] == FLOWER_MAN) {
                            // 找到人物
                            updatePlayerPosition(h, l)
                            Log.d(
                                ">>>>",
                                "$drawBitmapWidth -> onback find: -> ${squares[h][l].startX}"
                            )
                        }
                    }
                }
                invalidate()  // 刷新画布
            }
        } else {
            Log.d(">>>>", "onBack: empty")
        }
    }


    interface GameStateListener {
        fun passed(level: Int)
        fun gameOver()
        fun competeAllLevels()
    }

    private fun deepCopy(array: Array<IntArray>): Array<IntArray> {
        val copy = Array(array.size) { IntArray(array[it].size) }
        for (i in array.indices) {
            for (j in array[i].indices) {
                copy[i][j] = array[i][j]
            }
        }
        return copy
    }

    /**
     * 重置数据
     */
    fun resetData() {
        CURRENT_ORIENTATION = MOVE_TO_DOWN
        mapTempList.clear()
        setMap(level)
    }

    // 判断是否有方块正在进行动画
    private fun isAnimating(): Boolean {
        return squares.flatten().any { it.isAnimating() }
    }

    // 更新所有方块的位置
    private fun updateSquarePositions() {
        /* for (x in 0 until MAP_H) {
             for (y in 0 until MAP_L) {
                 squares[x][y].updatePosition()
             }
         }*/
        squares[playerStartRow][playerStartCol].updatePosition()
    }

    // 移动指定方块到目标位置，并触发动画
    fun moveSquareTo(row: Int, col: Int) {
        if (row in 0 until MAP_H
            && col in 0 until MAP_L
            && !squares[playerStartRow][playerStartCol].isAnimating()
        ) {
            squares[playerStartRow][playerStartCol].moveTo(row, col)
            startAnimation()
        }
    }

    var drawCount = 0

    // 开始动画
    private fun startAnimation() {
        drawCount = 0
        val animator = ValueAnimator.ofFloat(0f, 1f).apply {
            duration = animationDuration
            addUpdateListener { animation ->
                invalidate()
            }
        }
        animator.start()
    }

    inner class Square(var startX: Int = 0, var startY: Int = 0) {
        var targetX = startX
        var targetY = startY
        var animationProgress = 0f

        fun moveTo(row: Int, col: Int) {
            targetX = gridBounds[row][col].left
            targetY = gridBounds[row][col].top
            animationProgress = 0f
        }

        fun isAnimating(): Boolean {
            return targetX != startX || targetY != startY
        }

        fun updatePosition() {
            val stepSize = 1.0f / animationDuration

            startX = (startX + (targetX - startX) * animationProgress).toInt()
            startY = (startY + (targetY - startY) * animationProgress).toInt()

            animationProgress += stepSize
            if (animationProgress >= 1f) {
                animationProgress = 0f
                startX = targetX
                startY = targetY
                updatePlayerPosition(playerEndRow, playerEndCol)
                Log.d(">>>>", " move over startrow-> $playerStartRow startCol -> $playerStartCol")
            }
        }
    }
}